package Concurrency2.Inteview01_ThreadPool.version01;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 作用:
 * version1线程池 - 实现最基本的线程池功能, 提交任务, 关闭线程池
 */
public class SimpleThreadPool implements ThreadPool {

    // 属性: 初始线程数
    private int initialSize;
    // 属性: 任务队列
    private BlockingQueue<Runnable> taskQueue;
    // 属性: 工作线程集合
    private List<WorkerThread> threads;
    // 属性: shutdown状态标志
    private volatile boolean isShutdown = false;


    // 构造: 创建具有初始线程数的线程池实例
    public SimpleThreadPool(int initialSize) {
        this.initialSize = initialSize;
        this.taskQueue = new LinkedBlockingQueue<>(); //无界队列
        this.threads = new ArrayList<>(initialSize);
        // 初始化指定数量的工作线程, 并启动
        for (int i = 0; i < initialSize; i++) {
            WorkerThread workerThread = new WorkerThread(taskQueue);
            workerThread.start();
            threads.add(workerThread);
        }
        // 启动日志
        System.out.println("--Thread pool initialization completed.--");
    }

    /**
     * 功能1: 提交任务到线程池
     *
     * @param task 任务
     */
    @Override
    public void execute(Runnable task) {
        if (isShutdown) {
            throw new IllegalStateException("ThreadPool has been shutdown.");
        }
        taskQueue.offer(task); // 无界队列, 使用非阻塞方法
    }

    /**
     * 功能2: 关闭线程池
     */
    @Override
    public void shutdown() {
        //1, 设置线程池状态
        isShutdown = true;
        //2, 中断worker线程
        for (WorkerThread worker : threads) {
            worker.interrupt();
        }
    }

    /**
     * 功能3: 立即关闭线程池
     *
     * @return 未执行的任务列表
     */
    @Override
    public List<Runnable> shutdownNow() {
        //1, 设置线程池状态
        isShutdown = true;
        //2, 保留为执行的任务作为结果返回
        List<Runnable> remainTask = new ArrayList<>();
        taskQueue.drainTo(remainTask);
        //3, 中断worker线程
        for (WorkerThread worker : threads) {
            worker.interrupt();
        }
        return remainTask;
    }
}
